package UIFree
{
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.geom.Point;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;

	public class uif_loader extends Loader {
		
		public static const LD_LOAD: String 		= 'LD_LOAD';
		public static const LD_UNLOAD: String 		= 'LD_UNLOAD';
		public static const LD_COMPLETE: String 	= 'LD_COMPLETE';
		public static const LD_ERROR: String 		= 'LD_ERROR';
		public static const LD_REMOVE: String 		= 'LD_REMOVE';
		public static var disp: EventDispatcher	= null;
		
		private static var _cache: Object;
		public static var CACHE_ENABLED: Boolean = false;

//		private var _loadURL: String;
		private var _sourceUrl	: String;
		private var _loaded		: int;
		public var _data		: Object;
		
		public function uif_loader(a_parent: Sprite=null, URL: String='', 
					a_onComplete: Function=null, a_x: Number=0, a_y:Number=0, context: LoaderContext=null) {
			super();
			
			if (CACHE_ENABLED && !_cache) _cache = new Object();
			if (a_parent) a_parent.addChild(this);
			_sourceUrl = '';
			x = a_x;
			y = a_y;
			
			contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function(e: Event): void {
				_loaded = 0;
				ld_dispatchEvent(new ObjectEvent(LD_ERROR, this));
			});
			contentLoaderInfo.addEventListener(Event.INIT, function(e: Event): void {
				var li: LoaderInfo = (e.target as LoaderInfo)
				var url: String = li.loader['sourceUrl'];
				_loaded = 1;
				ld_dispatchEvent(new ObjectEvent(LD_COMPLETE, this));
				if (CACHE_ENABLED && !_cache[url] && (contentLoaderInfo.bytes != null)) _cache[url] = clone();
			});

			if (URL) load(new URLRequest(URL), context);
			if (a_onComplete != null) contentLoaderInfo.addEventListener(Event.INIT, a_onComplete);
		}
		
		public function get This(): uif_loader {
			return this;
		}
		
		protected function ld_dispatchEvent(event: Event): void {
			if (disp != null) disp.dispatchEvent(event);
		}
		
		override public function load(request:URLRequest, a_context:LoaderContext=null):void {
			doBeforeLoad(-1);
//			_loadURL = request.url;
			ld_dispatchEvent(new ObjectEvent(LD_LOAD, this));
			if (CACHE_ENABLED && _cache[request.url]) 
				(_cache[request.url] as uif_loader).duplicate(this);
			else super.load(request, a_context?a_context:(new LoaderContext(true)));
		}
		
		override public function loadBytes(bytes:ByteArray, context:LoaderContext=null):void {
			doBeforeLoad(-1);
			ld_dispatchEvent(new ObjectEvent(LD_LOAD, this));
			super.loadBytes(bytes, context);
		}
		
		override public function unload():void {
			doBeforeLoad(0);
			ld_dispatchEvent(new ObjectEvent(LD_UNLOAD, this));
			super.unload();
		}
		
		protected function doBeforeLoad(a_loaded: int): void {
			if (_loaded == -1) ld_dispatchEvent(new ObjectEvent(LD_COMPLETE, this));
			_loaded = a_loaded;
		}
		
		public function dispose(): void {
			unload();
			if (parent) parent.removeChild(this);
		}
		
		public function get sourceUrl(): String {
			return _sourceUrl?_sourceUrl:(contentLoaderInfo.url?contentLoaderInfo.url:'');
		}
		
		public function get loaded(): Boolean {
			return _loaded == 1;
		}
		
		public function duplicate(target: Loader=null): Loader {
			if (!target) target = new uif_loader();
			
			if (!loaded) {
				function doDubLoad(e: Event): void {
					contentLoaderInfo.removeEventListener(Event.COMPLETE, doDubLoad);
					duplicate(target);		
				}
				contentLoaderInfo.addEventListener(Event.COMPLETE, doDubLoad);	
			} else {
				target.loadBytes(contentLoaderInfo.bytes);
				if (target is uif_loader)
					(target as uif_loader)._sourceUrl = sourceUrl;
			}
			return target;
		}
		
		public function get size(): Point {
			return new Point(contentLoaderInfo.width, contentLoaderInfo.height);
		}
		
		public function clone(onClone: Function=null): uif_loader {
			var result: uif_loader = new uif_loader();
			if (onClone != null) {
				function doLoad(e: Event): void {
					result.contentLoaderInfo.removeEventListener(Event.COMPLETE, doLoad);
					onClone(e);
				}
				result.contentLoaderInfo.addEventListener(Event.COMPLETE, doLoad);
			}
			duplicate(result);
			return result;
		}
		
		public function get bitmapContentAccess(): Boolean {
			try {
				if (contentLoaderInfo.content) return true
			} catch (err: Error) {
			}
			return false;
		}
	}
}